12. Exercise: Creating a Room Database
L6 19 Room Database Code SC
Now it’s your turn to complete this exercise yourself.
In this step, you'll write the code to create a Room database for your app.
In
SleepDatabase.kt, create an abstract class that extendsRoomDatabase.Annotate the class with
@Databaseand supply theSleepNightforentities,versionas1, andexportSchemaset tofalse.
@Database(entities = [SleepNight::class], version = 1, exportSchema = false)
abstract class SleepDatabase : RoomDatabase() {
- Declare an
abstractvalue that returns theSleepDatabaseDao:
abstract val sleepDatabaseDao: SleepDatabaseDao
- Below, define a companion object:
companion object {}
Inside the companion object, declare a private nullable variable
INSTANCEfor the database.Initialize it to null, and annotate
INSTANCEwith@Volatile:
@Volatile
private var INSTANCE: SleepDatabase? = null
- Below, still inside the companion object, define the
getInstance()method with aContextparameter, which will return a reference to theSleepDatabase:
fun getInstance(context: Context): SleepDatabase {}
- Inside
getInstance()add asynchronized{}block, and pass inthis:
synchronized(this) {}
- Inside the
synchronizedblock, copy the current value ofINSTANCEto a local variable,instance:
var instance = INSTANCE
- At the end of the
synchronizedblock, still inside the block, returninstance:
return instance
Above the return statement, check if there is already a database stored in
instance.If
instanceisnull, use the database builder to get a database:
if (instance == null) {}
- Invoke Room’s
databaseBuilderand supply the context that we passed in, the database class, and a name for the database:
instance = Room.databaseBuilder(
context.applicationContext,
SleepDatabase::class.java,
"sleep_history_database"
)
- Add the required migration strategy to the builder:
.fallbackToDestructiveMigration()
- And call
.build():
.build()
- Assign
INSTANCE = instanceas the final step inside theifstatement:
INSTANCE = instance
- Your final code should look like this:
@Database(entities = [SleepNight::class], version = 1, exportSchema = false)
abstract class SleepDatabase : RoomDatabase() {
abstract val sleepDatabaseDao: SleepDatabaseDao
companion object {
@Volatile
private var INSTANCE: SleepDatabase? = null
fun getInstance(context: Context): SleepDatabase {
synchronized(this) {
var instance = INSTANCE
if (instance == null) {
instance = Room.databaseBuilder(
context.applicationContext,
SleepDatabase::class.java,
"sleep_history_database"
)
.fallbackToDestructiveMigration()
.build()
INSTANCE = instance
}
return instance
}
}
}
}
- Build and run your code to make sure there are no basic errors.
If you want to start at this step, you can download this exercise from: Step.03-Exercise-Create-RoomDatabase.
You will find plenty of //TODO comments to help you complete this exercise, and if you get stuck, go back and watch the video again.
Once you’re done, you can check your solution against the solution we’ve provided here: Step.03-Solution-Create-RoomDatabase, or using this git diff.
Task Description:
Complete these tasks to create the Room database.
Task Feedback:
Great, you've just completed a key part of your app!
Android Developer Documentation
- Room Database
- Database (annotations)
- Raw queries with Room
- RoomDatabase.Builder
- Migrating Room Databases
Other documentation and articles
- Singleton
- From Google Developer Experts: On properly using volatile and synchronized
- Companion objects
- Understanding Migrations with Room
- Testing Migrations with Room